
L'analyse exploratoire tient près d'1/3 du volume de cette page. Pour aller droit au but, rdv au 1-3
C:\Users\Wince\Downloads\OC\Projet_6\data
INFO:tensorflow:Enabling eager execution
INFO:tensorflow:Enabling v2 tensorshape
INFO:tensorflow:Enabling resource variables
INFO:tensorflow:Enabling tensor equality
INFO:tensorflow:Enabling control flow v2
On crée un paramètre debug afin de pouvoir exécuter le programme en mode rapide, on ne chargera que des quantités échantillonnesques de données tant que l'on laisse ce paramètre true. Les quantités de données correspondant aux modes debug/normal sont définies à chaque étape correspondant au chargement en ram des différentes données utilisées.
Pour l'EDA, je rappelle des fonctions écrites lors des projets OC précédents que j'ai stockées dans un script. Les fonctions utilisées sont recopiées dans la cellule ci-dessous afin que le livrable soit autoporteur. La lecture du code n'est donc pas nécessairement pertinente.
On change de répertoire de travail :
C:\Users\Wince\Downloads\OC\Projet_6\Data\extracted
Puis on charge tout ou partie de nos données texte (50% en mode debug, l'intégralité sinon) :
fichier yelp_academic_dataset_business.json chargé
fichier yelp_academic_dataset_checkin.json chargé
fichier yelp_academic_dataset_review.json chargé
fichier yelp_academic_dataset_tip.json chargé
fichier yelp_academic_dataset_user.json chargé
On exécute la fonction d'écriture des infos sur l'ensemble des df chargés, puis on lit le rapport d'EDA obtenu :
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
INFORMATIONS DE BASE SUR LE DATAFRAME : BUSINESS
Dimensions du dataframe : (104697, 14)
Types de données contenues:
n_features
object 9
float64 3
int64 2
Taux de remplissage des 14 premières variables par ordre décroissant :
0
business_id 1.000000
business_name 1.000000
address 1.000000
city 1.000000
state 1.000000
postal_code 1.000000
latitude 1.000000
longitude 1.000000
stars 1.000000
review_count 1.000000
is_open 1.000000
categories 0.997469
attributes 0.860674
hours 0.785667
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES CATEGORIES DU DATAFRAME BUSINESS
--------------------------------------------------------------------------------------------------------------------
| business_id | business_name | address | city | state | postal_code | attributes | categories | hours | |
|---|---|---|---|---|---|---|---|---|---|
| count | 104697 | 104697 | 104697 | 104697 | 104697 | 104697 | 90110 | 104432 | 82257 |
| unique | 104697 | 82692 | 88447 | 916 | 30 | 13055 | 41429 | 56040 | 32764 |
| top | X2ptpkcla0XFftCAJG6aMA | Starbucks | Las Vegas | AZ | 89109 | {'BusinessAcceptsCreditCards': 'True'} | Pizza, Restaurants | {'Monday': '0:0-0:0', 'Tuesday': '0:0-0:0', 'W... | |
| freq | 1 | 577 | 4283 | 15894 | 30434 | 1654 | 6039 | 522 | 4482 |
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES VARIABLES NUMERIQUES DU DATAFRAME BUSINESS
--------------------------------------------------------------------------------------------------------------------
| latitude | longitude | stars | review_count | is_open | |
|---|---|---|---|---|---|
| count | 104697.000000 | 104697.000000 | 104697.000000 | 104697.000000 | 104697.000000 |
| mean | 38.576321 | -97.402491 | 3.540546 | 36.510473 | 0.806537 |
| std | 4.934096 | 16.726664 | 1.022580 | 115.978076 | 0.395015 |
| min | 33.103471 | -123.048908 | 1.000000 | 3.000000 | 0.000000 |
| 25% | 33.638633 | -112.266857 | 3.000000 | 4.000000 | 1.000000 |
| 50% | 36.148362 | -111.743902 | 3.500000 | 9.000000 | 1.000000 |
| 75% | 43.612944 | -79.969530 | 4.500000 | 27.000000 | 1.000000 |
| max | 51.299943 | -72.911982 | 5.000000 | 6751.000000 | 1.000000 |
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
INFORMATIONS DE BASE SUR LE DATAFRAME : CHECKIN
Dimensions du dataframe : (87594, 2)
Types de données contenues:
n_features
object 2
Taux de remplissage des 2 premières variables par ordre décroissant :
0
business_id 1.0
date 1.0
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES CATEGORIES DU DATAFRAME CHECKIN
--------------------------------------------------------------------------------------------------------------------
| business_id | date | |
|---|---|---|
| count | 87594 | 87594 |
| unique | 87594 | 87594 |
| top | oKLoaYeAjRhuXX73Dzw1TQ | 2010-06-19 17:13:00, 2010-07-31 16:40:24, 2010... |
| freq | 1 | 1 |
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES VARIABLES NUMERIQUES DU DATAFRAME CHECKIN
--------------------------------------------------------------------------------------------------------------------
PAS DE VARIABLE NUMERIQUE DANS LE DF CHECKIN
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
INFORMATIONS DE BASE SUR LE DATAFRAME : REVIEW
Dimensions du dataframe : (4010561, 9)
Types de données contenues:
n_features
object 5
int64 3
float64 1
Taux de remplissage des 9 premières variables par ordre décroissant :
0
review_id 1.0
user_id 1.0
business_id 1.0
stars 1.0
useful 1.0
funny 1.0
cool 1.0
text 1.0
date 1.0
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES CATEGORIES DU DATAFRAME REVIEW
--------------------------------------------------------------------------------------------------------------------
| review_id | user_id | business_id | text | date | |
|---|---|---|---|---|---|
| count | 4010561 | 4010561 | 4010561 | 4010561 | 4010561 |
| unique | 4010561 | 1338211 | 203210 | 4004871 | 3968055 |
| top | NLzxbtrwAqDmTdW84vfR2g | CxDOIDnH8gp9KXzpBHJYXw | RESDUcs7fIiihp38-d6_6g | . | 2014-07-27 01:48:29 |
| freq | 1 | 2176 | 5233 | 10 | 5 |
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES VARIABLES NUMERIQUES DU DATAFRAME REVIEW
--------------------------------------------------------------------------------------------------------------------
| stars | useful | funny | cool | |
|---|---|---|---|---|
| count | 4.010561e+06 | 4.010561e+06 | 4.010561e+06 | 4.010561e+06 |
| mean | 3.702447e+00 | 1.323804e+00 | 4.597324e-01 | 5.753881e-01 |
| std | 1.490945e+00 | 3.521639e+00 | 2.202823e+00 | 2.476259e+00 |
| min | 1.000000e+00 | -1.000000e+00 | 0.000000e+00 | -1.000000e+00 |
| 25% | 3.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 |
| 50% | 4.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 |
| 75% | 5.000000e+00 | 1.000000e+00 | 0.000000e+00 | 0.000000e+00 |
| max | 5.000000e+00 | 7.580000e+02 | 9.760000e+02 | 3.210000e+02 |
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
INFORMATIONS DE BASE SUR LE DATAFRAME : TIP
Dimensions du dataframe : (660381, 5)
Types de données contenues:
n_features
object 4
int64 1
Taux de remplissage des 5 premières variables par ordre décroissant :
0
user_id 1.0
business_id 1.0
text 1.0
date 1.0
compliment_count 1.0
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES CATEGORIES DU DATAFRAME TIP
--------------------------------------------------------------------------------------------------------------------
| user_id | business_id | text | date | |
|---|---|---|---|---|
| count | 660381 | 660381 | 660381 | 660381 |
| unique | 236308 | 105183 | 623722 | 659176 |
| top | mkbx55W8B8aPLgDqex7qgg | FaHADZARwnY4yvlvpnsfGA | Love this place! | 2014-03-26 14:21:09 |
| freq | 1344 | 1891 | 382 | 3 |
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES VARIABLES NUMERIQUES DU DATAFRAME TIP
--------------------------------------------------------------------------------------------------------------------
| compliment_count | |
|---|---|
| count | 660381.000000 |
| mean | 0.015735 |
| std | 0.142381 |
| min | 0.000000 |
| 25% | 0.000000 |
| 50% | 0.000000 |
| 75% | 0.000000 |
| max | 15.000000 |
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
INFORMATIONS DE BASE SUR LE DATAFRAME : USER
Dimensions du dataframe : (984352, 22)
Types de données contenues:
n_features
int64 16
object 5
float64 1
Taux de remplissage des 22 premières variables par ordre décroissant :
0
user_id 1.0
compliment_funny 1.0
compliment_cool 1.0
compliment_plain 1.0
compliment_note 1.0
compliment_list 1.0
compliment_cute 1.0
compliment_profile 1.0
compliment_more 1.0
compliment_hot 1.0
average_stars 1.0
fans 1.0
friends 1.0
elite 1.0
cool 1.0
funny 1.0
useful 1.0
yelping_since 1.0
review_count 1.0
user_name 1.0
compliment_writer 1.0
compliment_photos 1.0
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES CATEGORIES DU DATAFRAME USER
--------------------------------------------------------------------------------------------------------------------
| user_id | user_name | yelping_since | elite | friends | |
|---|---|---|---|---|---|
| count | 984352 | 984352 | 984352 | 984352 | 984352 |
| unique | 984352 | 88209 | 982332 | 588 | 560595 |
| top | _JTML2L1KnYpk8FTRRlbng | John | 2011-12-02 01:26:05 | None | |
| freq | 1 | 8499 | 3 | 946384 | 417593 |
--------------------------------------------------------------------------------------------------------------------
TABLEAU DESCRIPTIF DES VARIABLES NUMERIQUES DU DATAFRAME USER
--------------------------------------------------------------------------------------------------------------------
| review_count | useful | funny | cool | fans | average_stars | compliment_hot | compliment_more | compliment_profile | compliment_cute | compliment_list | compliment_note | compliment_plain | compliment_cool | compliment_funny | compliment_writer | compliment_photos | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 | 984352.000000 |
| mean | 22.155302 | 39.790619 | 16.996852 | 21.654156 | 1.469823 | 3.649472 | 2.016972 | 0.297901 | 0.186260 | 0.153538 | 0.065876 | 1.421096 | 2.865094 | 2.846068 | 2.846068 | 1.064892 | 1.110578 |
| std | 74.283752 | 508.231646 | 357.999006 | 442.979536 | 18.900354 | 1.171499 | 73.822129 | 9.415525 | 12.427079 | 5.973962 | 4.732114 | 76.363858 | 84.641509 | 83.533235 | 83.533235 | 30.014581 | 73.777200 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 2.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 3.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 50% | 5.000000 | 3.000000 | 0.000000 | 0.000000 | 0.000000 | 3.880000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 75% | 15.000000 | 13.000000 | 3.000000 | 3.000000 | 0.000000 | 4.570000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| max | 9875.000000 | 197130.000000 | 165861.000000 | 191359.000000 | 11568.000000 | 5.000000 | 25452.000000 | 4102.000000 | 6711.000000 | 1968.000000 | 2461.000000 | 58480.000000 | 25546.000000 | 27885.000000 | 27885.000000 | 10944.000000 | 42826.000000 |
--------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------
D'abord le boxplot des variables continues :
Pour aller un peu plus loin, on regarder les valeurs que prend la variable attributes :
There was an error when executing cell [10]. Please run Voilà with --debug to see the error message.
{'BusinessAcceptsCreditCards': 'True'} 6039
{'ByAppointmentOnly': 'True', 'BusinessAcceptsCreditCards': 'True'} 2310
{'ByAppointmentOnly': 'False', 'BusinessAcceptsCreditCards': 'True'} 1792
{'ByAppointmentOnly': 'True'} 1648
{'ByAppointmentOnly': 'True', 'BusinessAcceptsCreditCards': 'True', 'AcceptsInsurance': 'True'} 1103
...
{'GoodForMeal': '{'dessert': False, 'latenight': False, 'lunch': False, 'dinner': False, 'brunch': False, 'breakfast': False}', 'RestaurantsTakeOut': 'True', 'BikeParking': 'True', 'RestaurantsDelivery': 'False', 'Ambience': '{'touristy': False, 'hipster': False, 'romantic': False, 'intimate': False, 'trendy': False, 'upscale': False, 'classy': False, 'casual': False}', 'GoodForKids': 'True', 'RestaurantsReservations': 'False', 'RestaurantsPriceRange2': '2', 'HasTV': 'True', 'BusinessParking': '{'garage': False, 'street': False, 'validated': False, 'lot': False, 'valet': False}', 'WiFi': ''free'', 'RestaurantsGoodForGroups': 'True', 'RestaurantsAttire': ''casual'', 'OutdoorSeating': 'False'} 1
{'Alcohol': 'u'full_bar'', 'BusinessAcceptsCreditCards': 'True', 'RestaurantsPriceRange2': '2', 'RestaurantsGoodForGroups': 'True', 'GoodForKids': 'True', 'RestaurantsTakeOut': 'True', 'RestaurantsAttire': 'u'casual'', 'RestaurantsDelivery': 'False', 'BusinessParking': '{'garage': False, 'street': False, 'validated': False, 'lot': False, 'valet': False}'} 1
{'GoodForDancing': 'False', 'Alcohol': ''full_bar'', 'HappyHour': 'True', 'Caters': 'False', 'NoiseLevel': ''average'', 'OutdoorSeating': 'True', 'CoatCheck': 'False', 'BusinessAcceptsCreditCards': 'True', 'BusinessParking': '{'garage': False, 'street': True, 'validated': False, 'lot': False, 'valet': False}', 'DriveThru': 'False', 'RestaurantsTakeOut': 'True', 'BestNights': '{'monday': False, 'tuesday': False, 'friday': False, 'wednesday': False, 'thursday': False, 'sunday': False, 'saturday': True}', 'WheelchairAccessible': 'True', 'Music': '{'dj': False, 'background_music': False, 'no_music': False, 'jukebox': False, 'live': True, 'video': False, 'karaoke': False}', 'RestaurantsTableService': 'True', 'RestaurantsAttire': ''casual'', 'RestaurantsGoodForGroups': 'True', 'WiFi': 'u'free'', 'DogsAllowed': 'False', 'RestaurantsDelivery': 'False', 'HasTV': 'True', 'Ambience': '{'touristy': False, 'hipster': None, 'romantic': None, 'divey': False, 'intimate': True, 'trendy': True, 'upscale': None, 'classy': None, 'casual': True}', 'GoodForMeal': '{'dessert': None, 'latenight': None, 'lunch': True, 'dinner': True, 'brunch': True, 'breakfast': True}', 'RestaurantsPriceRange2': '2', 'RestaurantsReservations': 'True', 'GoodForKids': 'False'} 1
{'RestaurantsPriceRange2': '2', 'GoodForKids': 'False', 'OutdoorSeating': 'True', 'RestaurantsGoodForGroups': 'True', 'BikeParking': 'True', 'Alcohol': 'u'full_bar'', 'NoiseLevel': 'u'loud'', 'HasTV': 'True', 'Music': '{'dj': False, 'background_music': False, 'no_music': False, 'jukebox': False, 'live': True, 'video': False, 'karaoke': False}', 'HappyHour': 'True', 'BusinessParking': '{'garage': False, 'street': False, 'validated': False, 'lot': False, 'valet': False}', 'Ambience': '{'touristy': False, 'hipster': False, 'romantic': False, 'intimate': True, 'trendy': False, 'upscale': False, 'classy': True, 'casual': True}'} 1
{'RestaurantsTakeOut': 'True', 'Alcohol': 'u'none'', 'RestaurantsReservations': 'True', 'Ambience': '{'romantic': False, 'intimate': False, 'classy': False, 'upscale': False, 'touristy': False, 'trendy': False, 'hipster': False, 'casual': False}', 'NoiseLevel': 'u'loud'', 'GoodForKids': 'True', 'OutdoorSeating': 'False', 'RestaurantsGoodForGroups': 'True', 'RestaurantsAttire': 'u'casual'', 'HasTV': 'False', 'BusinessParking': '{'garage': False, 'street': False, 'validated': False, 'lot': False, 'valet': False}'} 1
Name: attributes, Length: 41429, dtype: int64
Puis celles que prend la variable categories :
Pizza, Restaurants 522 Restaurants, Pizza 518 Nail Salons, Beauty & Spas 499 Beauty & Spas, Nail Salons 492 Food, Coffee & Tea 470 Coffee & Tea, Food 468 Mexican, Restaurants 464 Restaurants, Chinese 446 Restaurants, Mexican 437 Hair Salons, Beauty & Spas 431 Beauty & Spas, Hair Salons 420 Chinese, Restaurants 390 Auto Repair, Automotive 289 Automotive, Auto Repair 287 Banks & Credit Unions, Financial Services 262 Italian, Restaurants 245 Grocery, Food 239 Financial Services, Banks & Credit Unions 235 Food, Grocery 234 Restaurants, Italian 220 Beauty & Spas, Barbers 214 Apartments, Real Estate, Home Services 214 Apartments, Home Services, Real Estate 208 Real Estate, Apartments, Home Services 206 Real Estate, Home Services, Apartments 205 Home Services, Apartments, Real Estate 198 Food, Ice Cream & Frozen Yogurt 192 Home Services, Real Estate, Apartments 182 Ice Cream & Frozen Yogurt, Food 181 Barbers, Beauty & Spas 175 Restaurants, Sandwiches, Fast Food 171 Pets, Veterinarians 161 Bakeries, Food 157 Vietnamese, Restaurants 153 Car Rental, Hotels & Travel 152 Sandwiches, Restaurants, Fast Food 149 Restaurants, Thai 146 Food, Bakeries 143 Heating & Air Conditioning/HVAC, Home Services 140 Veterinarians, Pets 136 Home Services, Heating & Air Conditioning/HVAC 135 Hotels, Hotels & Travel, Event Planning & Services 134 Restaurants, American (Traditional) 134 Hotels & Travel, Car Rental 133 Automotive, Car Dealers 132 Health & Medical, Chiropractors 130 American (Traditional), Restaurants 128 Hotels, Event Planning & Services, Hotels & Travel 128 Restaurants, Vietnamese 125 Car Dealers, Automotive 124 Name: categories, dtype: int64
Enfin voyons comment la variable hours est structurée et ce qu'elle contient :
There was an error when executing cell [12]. Please run Voilà with --debug to see the error message.
{'Monday': '0:0-0:0', 'Tuesday': '0:0-0:0', 'Wednesday': '0:0-0:0', 'Thursday': '0:0-0:0', 'Friday': '0:0-0:0', 'Saturday': '0:0-0:0', 'Sunday': '0:0-0:0'} 4482
{'Monday': '8:0-17:0', 'Tuesday': '8:0-17:0', 'Wednesday': '8:0-17:0', 'Thursday': '8:0-17:0', 'Friday': '8:0-17:0'} 1630
{'Monday': '9:0-17:0', 'Tuesday': '9:0-17:0', 'Wednesday': '9:0-17:0', 'Thursday': '9:0-17:0', 'Friday': '9:0-17:0'} 1449
{'Monday': '10:0-21:0', 'Tuesday': '10:0-21:0', 'Wednesday': '10:0-21:0', 'Thursday': '10:0-21:0', 'Friday': '10:0-21:0', 'Saturday': '10:0-21:0', 'Sunday': '11:0-18:0'} 496
{'Monday': '11:0-22:0', 'Tuesday': '11:0-22:0', 'Wednesday': '11:0-22:0', 'Thursday': '11:0-22:0', 'Friday': '11:0-22:0', 'Saturday': '11:0-22:0', 'Sunday': '11:0-22:0'} 468
{'Monday': '11:0-22:0', 'Tuesday': '11:0-22:0', 'Wednesday': '11:0-22:0', 'Thursday': '11:0-22:0', 'Friday': '11:0-23:0', 'Saturday': '11:0-23:0', 'Sunday': '11:0-22:0'} 412
{'Monday': '8:30-17:0', 'Tuesday': '8:30-17:0', 'Wednesday': '8:30-17:0', 'Thursday': '8:30-17:0', 'Friday': '8:30-17:0'} 300
{'Monday': '11:0-21:0', 'Tuesday': '11:0-21:0', 'Wednesday': '11:0-21:0', 'Thursday': '11:0-21:0', 'Friday': '11:0-21:0', 'Saturday': '11:0-21:0', 'Sunday': '11:0-21:0'} 290
{'Monday': '10:0-22:0', 'Tuesday': '10:0-22:0', 'Wednesday': '10:0-22:0', 'Thursday': '10:0-22:0', 'Friday': '10:0-22:0', 'Saturday': '10:0-22:0', 'Sunday': '10:0-22:0'} 270
{'Monday': '9:0-21:0', 'Tuesday': '9:0-21:0', 'Wednesday': '9:0-21:0', 'Thursday': '9:0-21:0', 'Friday': '9:0-21:0', 'Saturday': '9:0-21:0', 'Sunday': '9:0-21:0'} 265
{'Monday': '11:0-23:0', 'Tuesday': '11:0-23:0', 'Wednesday': '11:0-23:0', 'Thursday': '11:0-23:0', 'Friday': '11:0-23:0', 'Saturday': '11:0-23:0', 'Sunday': '11:0-23:0'} 264
{'Monday': '9:0-17:0', 'Tuesday': '9:0-17:0', 'Wednesday': '9:0-17:0', 'Thursday': '9:0-17:0', 'Friday': '9:0-17:0', 'Saturday': '9:0-17:0', 'Sunday': '9:0-17:0'} 258
{'Monday': '9:0-17:0', 'Tuesday': '9:0-17:0', 'Wednesday': '9:0-17:0', 'Thursday': '9:0-17:0', 'Friday': '9:0-17:0', 'Saturday': '9:0-17:0'} 249
{'Monday': '0:0-0:0', 'Tuesday': '8:0-17:0', 'Wednesday': '8:0-17:0', 'Thursday': '8:0-17:0', 'Friday': '8:0-17:0'} 247
{'Monday': '7:0-17:0', 'Tuesday': '7:0-17:0', 'Wednesday': '7:0-17:0', 'Thursday': '7:0-17:0', 'Friday': '7:0-17:0'} 235
{'Monday': '8:0-16:0', 'Tuesday': '8:0-16:0', 'Wednesday': '8:0-16:0', 'Thursday': '8:0-16:0', 'Friday': '8:0-16:0'} 232
{'Monday': '8:0-22:0', 'Tuesday': '8:0-22:0', 'Wednesday': '8:0-22:0', 'Thursday': '8:0-22:0', 'Friday': '8:0-22:0', 'Saturday': '8:0-22:0', 'Sunday': '8:0-22:0'} 229
{'Monday': '9:0-18:0', 'Tuesday': '9:0-18:0', 'Wednesday': '9:0-18:0', 'Thursday': '9:0-18:0', 'Friday': '9:0-18:0'} 227
{'Monday': '11:0-2:0', 'Tuesday': '11:0-2:0', 'Wednesday': '11:0-2:0', 'Thursday': '11:0-2:0', 'Friday': '11:0-2:0', 'Saturday': '11:0-2:0', 'Sunday': '11:0-2:0'} 223
{'Monday': '8:0-18:0', 'Tuesday': '8:0-18:0', 'Wednesday': '8:0-18:0', 'Thursday': '8:0-18:0', 'Friday': '8:0-18:0'} 223
{'Monday': '8:0-20:0', 'Tuesday': '8:0-20:0', 'Wednesday': '8:0-20:0', 'Thursday': '8:0-20:0', 'Friday': '8:0-20:0', 'Saturday': '8:0-20:0', 'Sunday': '8:0-20:0'} 220
{'Monday': '8:0-17:0', 'Tuesday': '8:0-17:0', 'Wednesday': '8:0-17:0', 'Thursday': '8:0-17:0', 'Friday': '8:0-17:0', 'Saturday': '8:0-17:0'} 218
{'Monday': '11:0-21:0', 'Tuesday': '11:0-21:0', 'Wednesday': '11:0-21:0', 'Thursday': '11:0-21:0', 'Friday': '11:0-22:0', 'Saturday': '11:0-22:0', 'Sunday': '11:0-21:0'} 211
{'Monday': '10:0-18:0', 'Tuesday': '10:0-18:0', 'Wednesday': '10:0-18:0', 'Thursday': '10:0-18:0', 'Friday': '10:0-18:0', 'Saturday': '10:0-18:0'} 196
{'Monday': '7:0-19:0', 'Tuesday': '7:0-19:0', 'Wednesday': '7:0-19:0', 'Thursday': '7:0-19:0', 'Friday': '7:0-19:0', 'Saturday': '7:0-19:0', 'Sunday': '7:0-19:0'} 189
{'Monday': '9:0-18:0', 'Tuesday': '9:0-18:0', 'Wednesday': '9:0-18:0', 'Thursday': '9:0-18:0', 'Friday': '9:0-18:0', 'Saturday': '9:0-18:0'} 188
{'Monday': '0:0-0:0', 'Tuesday': '9:0-17:0', 'Wednesday': '9:0-17:0', 'Thursday': '9:0-17:0', 'Friday': '9:0-17:0'} 182
{'Monday': '7:0-22:0', 'Tuesday': '7:0-22:0', 'Wednesday': '7:0-22:0', 'Thursday': '7:0-22:0', 'Friday': '7:0-22:0', 'Saturday': '7:0-22:0', 'Sunday': '7:0-22:0'} 181
{'Monday': '11:0-23:0', 'Tuesday': '11:0-23:0', 'Wednesday': '11:0-23:0', 'Thursday': '11:0-23:0', 'Friday': '11:0-0:0', 'Saturday': '11:0-0:0', 'Sunday': '11:0-23:0'} 175
{'Monday': '6:0-0:0', 'Tuesday': '6:0-0:0', 'Wednesday': '6:0-0:0', 'Thursday': '6:0-0:0', 'Friday': '6:0-0:0', 'Saturday': '6:0-0:0', 'Sunday': '6:0-0:0'} 173
{'Monday': '8:0-18:0', 'Tuesday': '8:0-18:0', 'Wednesday': '8:0-18:0', 'Thursday': '8:0-18:0', 'Friday': '8:0-18:0', 'Saturday': '8:0-18:0'} 159
{'Monday': '10:0-21:0', 'Tuesday': '10:0-21:0', 'Wednesday': '10:0-21:0', 'Thursday': '10:0-21:0', 'Friday': '10:0-21:0', 'Saturday': '10:0-21:0', 'Sunday': '11:0-19:0'} 158
{'Monday': '7:0-16:0', 'Tuesday': '7:0-16:0', 'Wednesday': '7:0-16:0', 'Thursday': '7:0-16:0', 'Friday': '7:0-16:0'} 155
{'Monday': '10:0-21:0', 'Tuesday': '10:0-21:0', 'Wednesday': '10:0-21:0', 'Thursday': '10:0-21:0', 'Friday': '10:0-21:0', 'Saturday': '10:0-21:0', 'Sunday': '10:0-21:0'} 154
{'Monday': '6:0-22:0', 'Tuesday': '6:0-22:0', 'Wednesday': '6:0-22:0', 'Thursday': '6:0-22:0', 'Friday': '6:0-22:0', 'Saturday': '6:0-22:0', 'Sunday': '6:0-22:0'} 152
{'Monday': '9:0-18:0', 'Tuesday': '9:0-18:0', 'Wednesday': '9:0-18:0', 'Thursday': '9:0-18:0', 'Friday': '9:0-18:0', 'Saturday': '9:0-18:0', 'Sunday': '9:0-18:0'} 148
{'Monday': '8:0-17:0', 'Tuesday': '8:0-17:0', 'Wednesday': '8:0-17:0', 'Thursday': '8:0-17:0', 'Friday': '8:0-17:0', 'Saturday': '8:0-17:0', 'Sunday': '8:0-17:0'} 147
{'Monday': '6:0-23:0', 'Tuesday': '6:0-23:0', 'Wednesday': '6:0-23:0', 'Thursday': '6:0-23:0', 'Friday': '6:0-23:0', 'Saturday': '6:0-23:0', 'Sunday': '6:0-23:0'} 137
{'Monday': '7:0-21:0', 'Tuesday': '7:0-21:0', 'Wednesday': '7:0-21:0', 'Thursday': '7:0-21:0', 'Friday': '7:0-21:0', 'Saturday': '7:0-21:0', 'Sunday': '7:0-21:0'} 134
{'Monday': '8:0-16:30', 'Tuesday': '8:0-16:30', 'Wednesday': '8:0-16:30', 'Thursday': '8:0-16:30', 'Friday': '8:0-16:30'} 133
{'Monday': '7:0-23:0', 'Tuesday': '7:0-23:0', 'Wednesday': '7:0-23:0', 'Thursday': '7:0-23:0', 'Friday': '7:0-23:0', 'Saturday': '7:0-23:0', 'Sunday': '7:0-23:0'} 132
{'Monday': '8:0-21:0', 'Tuesday': '8:0-21:0', 'Wednesday': '8:0-21:0', 'Thursday': '8:0-21:0', 'Friday': '8:0-21:0', 'Saturday': '8:0-21:0', 'Sunday': '8:0-21:0'} 132
{'Monday': '9:0-22:0', 'Tuesday': '9:0-22:0', 'Wednesday': '9:0-22:0', 'Thursday': '9:0-22:0', 'Friday': '9:0-22:0', 'Saturday': '9:0-22:0', 'Sunday': '9:0-22:0'} 130
{'Monday': '9:0-18:0', 'Tuesday': '9:0-18:0', 'Wednesday': '9:0-18:0', 'Thursday': '9:0-18:0', 'Friday': '9:0-18:0', 'Saturday': '10:0-17:0'} 129
{'Monday': '10:0-23:0', 'Tuesday': '10:0-23:0', 'Wednesday': '10:0-23:0', 'Thursday': '10:0-23:0', 'Friday': '10:0-0:0', 'Saturday': '10:0-0:0', 'Sunday': '10:0-23:0'} 128
{'Monday': '8:30-17:30', 'Tuesday': '8:30-17:30', 'Wednesday': '8:30-17:30', 'Thursday': '8:30-17:30', 'Friday': '8:30-17:30'} 125
{'Monday': '7:0-18:0', 'Tuesday': '7:0-18:0', 'Wednesday': '7:0-18:0', 'Thursday': '7:0-18:0', 'Friday': '7:0-18:0'} 125
{'Monday': '9:0-18:0', 'Tuesday': '9:0-18:0', 'Wednesday': '9:0-18:0', 'Thursday': '9:0-18:0', 'Friday': '9:0-18:0', 'Saturday': '9:0-17:0'} 123
{'Monday': '10:0-20:0', 'Tuesday': '10:0-20:0', 'Wednesday': '10:0-20:0', 'Thursday': '10:0-20:0', 'Friday': '10:0-20:0', 'Saturday': '10:0-20:0', 'Sunday': '11:0-18:0'} 122
{'Monday': '8:0-17:0', 'Tuesday': '8:0-17:0', 'Wednesday': '8:0-17:0', 'Thursday': '8:0-17:0', 'Friday': '8:0-17:0', 'Saturday': '8:0-12:0'} 122
Name: hours, dtype: int64
Cette dernière ne nous sera pas d'une grande utilité pour le use case en cours.
On commence par l'analyse univariée :
946384
2018 5791
2017,2018 5146
2016,2017,2018 3085
2015,2016,2017,2018 2427
...
2011,2014,2015,2016 1
2009,2010,2011,2018 1
2007,2013,2014,2015,2016,2017 1
2010,2015 1
2008,2009,2010,2014,2015,2016,2017,2018 1
Name: elite, Length: 588, dtype: int64
None 417593
wd3xoNaDLib8dhQ7BxUl6g 67
mGHP3esQQqCEicHLRV-g5Q 63
Wc5L6iuvSNF5WGBlqIO8nw 61
GGTF7hnQi6D5W77_qiKlqg 58
...
m-En57kSrg-dQ4XaMOP_eg, oT5sAOo-b8TC4NWhoFBVow, i55p5mhW9XeRYr97Nu0Zkg, PZHVoHvj6ObprFEKxu3Zrw, G2akbDxqxytPYsY3ksEd4g, EVZ9JTTmy5rnLCOrObfxlQ, UC4EuGaiiIt33HR5zAV2VQ, GFHzt6XEhEtVk21subwzqQ, NW105m-SaeaUvkXVFH8Ryw, a6P0h7MFnSF6nSolYwbPNg, -m-wCzGAoocf5Nh1adNHHQ, UDPfscd4RzmcdJSbPslHhQ, lRRO2u891O3BG_xWnLNiMw, PjptMGHjUka4V3BmDHxbsQ, AIW2EqQzhZbbzhU8yNuuUQ, 7d2_Q_qLSphWNCKJ9vuCXQ, gZOLGzDdMTHjUAB2rH5nMA, w0NE4mCmte7SN8sIgg7XTw, 16DnkmzfgDNoHzaW0PL-lA, S_ELxIkpJP_pWGitnxvc3A, 7N7Pb1Q6G8wR_sBYy5Jwpw, O51BuPjfT9uCCbcCLudWXg, wXT93ypOW_gJRZs5pg0diQ, T7UH6tNGx9eABYJyJtk0Rg, 9zzR_V4tgkXDhWy99xrRzw, I7GU-QJez8EMvJLnWBLYEQ, bsP3cPYKRhKG26phhPlBPg, phiK71E703uyiDwFo93gww, eIxk3YGKulEEhoLRP6_a-w, 2rq_g3fQSbKO4Auaut5YQg, hdzTAN8DGJKRddkZ8279JQ, X4QDaW3JvKhQ64jYrh3lbg, KiaGal1obmWDU1CryA8N2A, LTHay9bnT56TRc-HH6o4aw, zvMA0Zyz1wA2kH_BGJoViA 1
Drv2CLQI3e_oboK7sOPDeA, yk21wIO8iH14CFM4jJfYlQ 1
0kRcXLpwJebeuaNtvG698w, KelZuy4_OUQw9iIulaRV2g, liG4v3BUYcxQzObTP5satQ, -ZGr21URq4cglW7Dff27qg, SXDV1Jxtl1rZ1sIcP_EhCw, rJ14Gnb828RFaSlWSURuMw, wU0KBMe2rAUDMrP6yvWfEg, IHMHWm4pktvjmEEVNB5htQ, 3-Cmo8V5aL_O-guXi5sHTg, 9qfKVFeVos7HXtJ4egTu2w, TNR73GqgVwhYSz9OH6HsOA, yaY6NKGMckd4_Ul4AVLYdw, wyqrMoD50jaRJF6SUJUqmA, g3P01duYwscx_XO5B9dp4Q, PWJypbFZjmkCRmpu-dn5Tg, Cn7lmZ1Pqj5TCtX_fRVlLw, oQn9oekDTdAmmivS5jh3AQ, lhe2Pg79wDWTm5q2wHHAuQ, 7PqYCFMI5Xpmye2tmE_k3w, JLuprvXi5w8QNOp8lqGkOQ, aw59bO-E3yX18oW1ZEj8jQ, eVnG0n1Fme6WAyaNIozw5w, orOnUgRmiFeGP23sCqzlHw, LaMyToqOgYRAai_GEyZ61w, hIMIFcbhqSvpmW2gbfWugg, m0VRaYQi1ZgFqJq23sbe8g, Dy9FiwdRaMDPPAlgGT13Eg, I3C70A5aehPAuDmWDGThMQ, H_n5-oPWV47wNO520tyvig, OEdQxHDdX_bEtVU23sO3_w, 16tjKOvMw_nOgNViq2LwOQ, QAZnOqx3eX47wv2-hxGmDg, CsmT2Yu8Z8J0pSNonG8PYg, Nd_6HVBgVS68EHQMKFVcOA, Fx5olbok5epxFKhFg3vz7w, hMDPbxNk7pK8vrHaOzAhDQ, dEL-czmGV-8aRsx0EweOqw, 5kmUIaCPpZSESUxFy2IZxw, zUXa7tq-w9HxAHEm8KWzbg, G4qMcxHPk37Ik2Y3dRwwMw, 7wVHmoC3vOogq-GsEuJWTw, 0tipwMd760Jj5tD7bZVKtQ, NMLrWkcTJyGr6vvy3H0ebg, W5fh2LR3Ltycd662YdXo2A, yb6N2sn5DjU88RmaHByU_Q, mDXklReE4jufaTSxOW5hCA, syVGpeZO2OqWTesxn46NXw, wh0SwG50PX4G0XU5MC-ViA, 1QORYI8CUnZVbYyxAfVtOQ, zbw1zmJR40b885g3HWvNTg, _EO6YRKPm8Xmj2V-ob0ybA, rIvaIu2LqwjyNYvAkLoOvQ, yojR2Otv6kNTwkH8MLdsLw, lxasIgElJxklhGxQ3T5_Lg, inVNGKFQNHqBkhGAzvFXgA, X4GFXP3ot95S1qTPuz9WEA, GWUi_9Namp-Obw5NUjiq3A, uO0mUF2Loh36CEGr--2qkg, 0gSdrxYRzVOsJvgm9Em6gg, WFIz7CbH3HZbzriPEM1OSg, 40uMOYmiRSxIHOQOtafauA, rh9Umk8UWpN7GR2-Owd_zg, L6kxprCkbFJ0MQHBt7_nKg, 3QMXCk3HFEBjPAUQtgcIaA, dZKWGq_753YyGD3Urgh0Cw, NoeoYv16jK-PQO2j9y8TFg, 5v4yJBcs7QUiB1Viz-qEUA, ooZSBmDtvisqk-KVE1tHLA, 8u5olQB_2QgiHMC5EaITCw, fY2-PUhDG1s8MJ2xb3kJZQ, 2BZnGg1Wu8jwdxSYdZtFBQ, ma_mb3c1bzwbrcZZEHpQMw, 0LVB3vdASJMv_KDZyFiU2Q, AuIXJfBNhKisx5ButEQDvA, 90k9BZhTDSRBHkK0xU1CXg, 4FGJ9G4Pz9zgmhEQzPY7mw, 0c6wyptE1rD8oqVbcujoHA, 6OZzw8t-Yd1HlEYTaf2rbQ, p19XldlGBRMpa4Qvh-tzdw, GMHQeunLybcuN9JrYkS63g, hhGmim2bMdE07s8Dpif_6g, 53FQwMFtAfB9cfMOb4B4mA, 3LHUFoOyA4S3xpJGhyfOPA, Dknkkm2UMcQbhGMONtyUUQ, bw17iRZyyXSHXUbZYQVCiQ, C3VQDVz33uJ7ndsSjv9YHQ, O7ErH3b2SO7zIELPujkblg, y4fa5iIu6d2TLaaJuOYKgQ, PZ9KsKcBfc_zN66Xpx6O_g, GPlHjMvij7kmuvle12YDaQ, LONcgr7gSagHIsW_cGMTFA, Ue_SI03mT13ZUco47--F_A, ZwSucGjmroYQKKLcw3BZ0A, M4pDvhMmAjerKJZm2QqlKQ, pZ1zxMVyKAt9REFIaQzLHg, 2OsaBVrwdgnsXXsEAlNQPA, KXBz89NSt9CCBXUpMeKjfw, mzUrd01N2Ic1OzbFbdlnZg, fUfnGchZHHXL15myI53wjg, DIUFRxjTnl6cp_PLk1d1zw, 5YroBB_ZElVcjLBkRZMw-A, S9nGe8mKqG6G766gzIsKHg, q7FbnJsxKdze-my9f-J4Bw, KS2MXTkblEzfycias8PdPg, rH0ADq1leewAl_gOt2Qqdw, cfBw70eg6tmFd-CkHZsatQ 1
Ae_LDTKWcMeuNoxMEwVh1Q, -KO2YmcCz_rnk2Id4wWbSQ, pz_h2gkvmaH92RK58yBMNg, 6iKhvcecubd3kRHnUX_uIA, TflEE0XyySOPXbSvyznuaA, NBFEZLgJjdCQVqyP-dverA, 3PLb19KiASZXGvhAF9D18A, eKLj3ZTpN_k48JOQyghi4A, 6-sTSxIaoZWNLZGoifbYMQ, bYP0vIuedFVZOE72mAqXVw, 1fVWOts7puirtc0uLxauKQ, w_LAY6-MWFypdX7poMm5aA, VsSnYwcG5Ci2qllFB7LTzw, ribj_RkwbZaGQLoNBRiGIQ, EFkGn7d_Q3dVBhvyixZUbA, 1J_AvqAWKJ9zyYQEhAaq5w, hVmLSSlJwOTzymS_BJic3g, cgIu5ebGWwlLzeVxU6PGFg, ZJou22MwyA9TyZtgUBV1uw, uC4E0anLlIGqWRZaIyVsIg, 4EfHoEQidqE_3BLAujD8pQ, FR80sNikeIF-kQJvALbZgg, LT836QnQtq3FhntKQ71J2w, u0rMrAa9kOj6c1WZ5hcpPw, zG_53760SaKSYNdlxf1ehQ, m5OqM-e7b42gLDuzc8zILQ, bi3-yMMJbwNzKIf7b55O0g, 9A0-0MYiSm8rXHMSBNvZ8A, a1sese9rdZITd4vAWyIb6w, fNSU4Jx1nwUnfa1I7qnugw, 3ZTe5IG2WQK7WSuoxcCL_w, yTkrR5w7ANhPW1o6Hm9JDQ, xkzGmM8bfdOTuRyWAb2TTg, tRH2oI3GiaeDN5KrtG4rNQ, b48usYtN0gI_mCsn9661OA, o2R2kXEVeLHwV5jaH-kYmA, ZqqYLpPCLMhLMSB6UK86_w, SAUBN14AWwZZh6MoYpmmtA, ZSvwPN6HyljREYjoR2t5nw, IulLwZ2yLcGKe3UNoshMKg, A88AQW0Ts-X87iAW8QQEqg, cFMpXfLv0_cJwnQbeezzBA, U44pOBmOAXr7PDCc1NStPg, ktfDUKCCfHs49jR2cH9dug, f2xVrfWl0tsIld38XvfXDw, YEAWr22s-G4KV4h95j9Y6A, OnvUQsVBM4bCnz_7n_HohA, b67mjakbcExVStSxR0SNTA, 07maSESxhEVfITxMFfujsA, RebcFk7_1qmniMClGWMlNw, HQ5j0Gc8gRdHUkeqimrnWQ, gHxlM71E1K9ukz8ruDbJQw, NhgU7RhuYYFmpkb1jlYJ6Q, bMzNsxNWn-xUOb8D3K3mKQ, 8nEBajgNWfiONH51QcmlCQ 1
uNQoPwWYo0MUbQ35H8iRuQ, kcCh6MYS9Ch9X-vJjeeTSQ, CQbJTuGBqtv-Fdn_Qc5otQ, pkZK9ZKAKA1rPOCSpwes3A, e73Q4GRpWp0gqS3socA0qA, rRmRJUOFQrVxJb0piDPlUA, Q0DNIbXcVreFspzGXimV-A, Vvi9bj149hjEcYw64M1TUA, Vhz9av3zXUE0unbWRJPR3g, g0nA-ORWyDaKuPkAocG3cw, 2-FAJFLYEuNgFji79EEn0Q, HNBAxSHxmCnpId99IBftAw, fhHwzzimN7hgzH6I2NEg6w, RSy0J85RJvX6RGDryU4ipQ, ZJA7_yk8muZnf4q-dEh8ZA, 6Yuej-MxMM1czcZI0urF6Q, 4sIgttft8pj7OKuazigdGA, 7UgAeOvnU3hcicep_Fxr7Q, 8tN9QQiARiLPp1GgTjyCCw, Qb2Qmi8gvo4D5VzAvXn1ig, f-vKA1CgX747w9GtHmKvLg, EAhs57_MR2K1BUsg-ZA_6g, phBqwiNGGFiqIh-MsHocBw, uW1sO0YkMPPWKsCgfUzMHQ, Ag4V4mX9PsxzYiF6RtZDEw, 8sZ5yL7AQXsWIl2MhmnDbA, z_AEXUB1NU6wRZNG3fGmGQ, phCReTo6_4b-dbBoJekIHg, Z2J5RliYq__mfnvIqozlCA, 9XKmCKSUKU4m3dsEihoOLQ, h0qIQTZwb6WHQbV2gASMcQ, wYThwwsb-SAU7_eYkLotQA, 6c_sTQVo-qD_gDTlsXniLw, ZE32I572w_3Y-Go5eFtmHQ, bbmJGvCBp0YwyPb7bodyfg, Q5MHoIhaiL9cX3hcnbJGiw, O10Gqs53YV236QjexHDhhA, oOa28Scrnun0HjcO50LYqg, 1p9zF-p3nq_nZNJs6HemKQ, G_R7AQVO90uvLFyA7sOcWw, X_JAOEJV54n9MZAf5fRZ2w, hWeLbgtfH6HsgJuINqtjuA, I4LsbUx_KIqhd2_p6GHLoQ, fmsfII4LgxnslIKoGd9i8A, 9bjrNBlWKJwhv3cukqSasg, KAt1-9a9keeah2e5wLlvlg, Hr1ZZxbBhbcguEVLQ6f32Q, sAEdnhWBEtvLakisRkruYA, rtB8dap9CF6wtYa6MLmo5w, njtKqi7GVT1XdlWYI8Aljw, F2YrpnH01HwMAHOjx5V6oQ, PMOLyfb7OGmcNbhqIpFR0g, oAaEhS13xAghaEq-vgYYdw, 8iPjYRDzEnB6cf4y6VUPGg, vEXU6wXcOlxnw9LwM5eIEQ, DAiqo9dh7kzx_egRFegVgQ, LlE0U85yHb3CKemPlmSWgg, 1kCl7DCJCISzsRWLdAtA6Q, hXuJG2mnCrXdrbz7lBNVNQ, aNkUgtXeRhX-6KdCS9lexQ, WPsAtukvJKk7ZlH_Js3yiQ, 4BkFPMMMEI_n-LEUGUvbYg, qH6oBz3Mzdeh7Uzkpe9NPw, dk1ZHCrvMquxG74Vz53Zzg, i-rL7LP958q5HqeG5gi4hw, oHDxRg0ugSgNjNhVvBR3Tw, ugx2BywdjAsdSWllCHb75g, VauCbw49UYz0fgQhCbfXWQ, 0MYNiwO7l3n1kW2vSx1Pgw, TKA97HKwwIVit_e4-DpUbA, LVWk6WtYYvuUoOtAurmVtA, _1b2QEvgrJbS2z5xk0AdiA, 4quK2PRKGyDV3lUbKINwaA, rfga-A6sJ64iGhWGv0lTYg, _prCn_9AkrN7-nPZl6qA_A, cSWeC9UMoHng77RCj3kSjg, nrhEbFSKLI0ko8ki9Zla5g 1
Name: friends, Length: 560595, dtype: int64
Toutes ces infos concernant les utilisateurs ne nous serviront pas
non plus pour détecter les sujets d'insatisfaction, ni pour classifier
des photos.
On commence par l'analyse univariée :
Ici, on trouve une variable "stars" qui semble être le rating général du business concerné.
Et d'autres marques d'appréciation qui peuvent être intéressantes, mais
comme on s'intéresse aux sujets d'insatisfaction, on n'utilisera pas ces
dernières.
Voyons enfin notre variable text :
0 Bloom was poppin' on Sunday morning- and for g...
1 Over priced. Casino had few slots to choose fr...
2 ZERO stars!!! We ordered delivery that was ove...
3 Poor service by a pregnant woman, food good , ...
4 Food is good staff is friendly! the buffet is ...
...
4010556 They have created the stupidest delivery syste...
4010557 I love my new haircut. I just moved to Vegas s...
4010558 Slow to be acknowledged for a table. Gluten fr...
4010559 This a review of the 6510 S Fort Apache store ...
4010560 I have been going to Wendy's Nails for the pas...
Name: text, Length: 4010561, dtype: object
C'est là dessus qu'on va travailler pour détecter les sujets d'insatisfaction.
On va traiter uniquement les restaurants, c'est à dire :
| business_id | business_name | address | city | state | postal_code | latitude | longitude | stars | review_count | is_open | attributes | categories | hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | TNQMnauUy5jposO9P6WcJQ | Farmer Boy Restaurant | 46323 Telegraph Rd | Amherst | OH | 44001 | 41.362226 | -82.220860 | 4.5 | 3 | 0 | {'RestaurantsDelivery': 'False', 'BusinessPark... | Salad, Burgers, Restaurants, Breakfast & Brunch | {'Monday': '7:0-20:0', 'Tuesday': '7:0-20:0', ... |
| 5 | OCes5zxvxRd_bE_ZfyZuJw | Pho Dau Bo Restaurant | 1525 Bristol Road W | Mississauga | ON | L5M 4Z1 | 43.586830 | -79.698705 | 3.5 | 29 | 1 | {'HasTV': 'True', 'RestaurantsGoodForGroups': ... | Vietnamese, Restaurants | {'Monday': '10:0-23:0', 'Tuesday': '10:0-23:0'... |
| 8 | 6sOBPz69VLgIvNAY7dowOg | Mei Chuen Fast Food Restaurant | 3301 Mcnicoll Ave, Unit 1 | Toronto | ON | M1V | 43.820141 | -79.261958 | 3.5 | 6 | 0 | {'RestaurantsReservations': 'False', 'Restaura... | Chinese, Restaurants | {'Monday': '9:0-21:0', 'Tuesday': '9:0-21:0', ... |
| 18 | 1GG8G4aWXKSV4oQr2E8f3w | Restaurante Tu Pueblo | 6222 N 43rd Ave | Glendale | AZ | 85031 | 33.526689 | -112.151795 | 3.5 | 5 | 1 | {'GoodForKids': 'True', 'RestaurantsGoodForGro... | Restaurants, Nightlife, Tacos, Bars, Mexican | {'Monday': '8:0-9:0', 'Tuesday': '8:0-21:0', '... |
| 19 | oz-U184llqjVIt398hLntQ | Sub Factory | 2155 E University Dr | Tempe | AZ | 85281 | 33.421326 | -111.893244 | 4.0 | 9 | 0 | {'BusinessAcceptsCreditCards': 'True', 'Restau... | Restaurants, Sandwiches | {'Monday': '10:0-20:30', 'Tuesday': '10:0-20:3... |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 104686 | k2wkwkwbCCoxhqMVjzbJZg | Wally's American Gastropub | 7704 East Doubletree Ranch Rd | Scottsdale | AZ | 85258 | 33.565201 | -111.915220 | 4.0 | 125 | 1 | {'BusinessParking': '{'garage': False, 'street... | Gastropubs, Restaurants, Nightlife, Salad, Pub... | {'Monday': '0:0-0:0', 'Tuesday': '11:0-21:0', ... |
| 104688 | SzRcfEpCCOPPxTsw1ljZLQ | Sedaghat Restaurant | 3342 Danforth Avenue | Scarborough | ON | M1L 1C8 | 43.693898 | -79.277510 | 4.0 | 12 | 1 | {'WiFi': 'u'no'', 'BikeParking': 'True', 'Good... | Canadian (New), Restaurants, Persian/Iranian, ... | {'Monday': '11:0-21:30', 'Tuesday': '11:0-21:3... |
| 104689 | QouAo7lqUhPtW7qZpkNS8g | La Cage | 1212 Avenue des Canadiens-de-Montréal | Montréal | QC | H3B 2S2 | 45.496670 | -73.569773 | 3.5 | 27 | 1 | {'RestaurantsTakeOut': 'True', 'RestaurantsDel... | Restaurants, Bars, Chicken Wings, Brasseries, ... | {'Monday': '11:0-23:0', 'Tuesday': '11:0-23:0'... |
| 104692 | 2XQCX26OnIC_pap-5E2EMQ | Umai Ramen | 641 N Stephanie St | Henderson | NV | 89014 | 36.066757 | -115.047746 | 4.5 | 187 | 1 | {'BusinessParking': '{'garage': False, 'street... | Restaurants, Ramen, Japanese | {'Monday': '11:0-22:0', 'Tuesday': '11:0-22:0'... |
| 104693 | CR4fW7p_6bpTkul1SdpRsg | Moe's Southwest Grill | 4724 Sharon Rd, Ste H | Charlotte | NC | 28210 | 35.147486 | -80.833352 | 2.5 | 35 | 1 | {'BusinessAcceptsCreditCards': 'True', 'Caters... | Fast Food, Latin American, Mexican, Spanish, T... | {'Monday': '11:0-21:0', 'Tuesday': '11:0-21:0'... |
31906 rows × 14 columns
On isole les reviews correspondant à des restaurants, et on a le df qui va nous servir de base pour
On va quand même nettoyer le texte grâce aux outils ntlk, pas si primitif...
Et avant tout, on ne retient que les reviews ayant généré un rating <3.
"Just awful. Only go there if you like eating deep fried salty variations of food. The waitress never washed her hands after picking her teeth and handed us the food right after. Could go on about this place but it's not worth my time. Just don't go here. The 5 star reviews are fake."
On commence par tokeniser nos commentaires :
array(['just', 'awful', 'only', 'go', 'there', 'if', 'you', 'like',
'eating', 'deep', 'fried', 'salty', 'variations', 'of', 'food',
'the', 'waitress', 'never', 'washed', 'her', 'hands', 'after',
'picking', 'her', 'teeth', 'and', 'handed', 'us', 'the', 'food',
'right', 'after', 'could', 'go', 'on', 'about', 'this', 'place',
'but', 'it', 's', 'not', 'worth', 'my', 'time', 'just', 'don', 't',
'go', 'here', 'the', '5', 'star', 'reviews', 'are', 'fake'],
dtype='<U10')
On met le dictionnaire des stopwords en anglais de nltk à jour, avant de les éliminer de nos tokens :
array(['awful', 'go', 'like', 'eating', 'deep', 'fried', 'salty',
'variations', 'food', 'waitress', 'never', 'washed', 'hands',
'picking', 'teeth', 'handed', 'us', 'food', 'right', 'could', 'go',
'place', 'worth', 'time', 'go', '5', 'star', 'reviews', 'fake'],
dtype='<U10')
array(['aw', 'go', 'like', 'eat', 'deep', 'fri', 'salti', 'variat',
'food', 'waitress', 'never', 'wash', 'hand', 'pick', 'teeth',
'hand', 'us', 'food', 'right', 'could', 'go', 'place', 'worth',
'time', 'go', '5', 'star', 'review', 'fake'], dtype='<U8')
On crée notre dictionnaire :
Voyons la taille de notre dictionnaire :
23290
C'est un peu gros, on va limiter la taille du vocabulaire de notre modèle. Voyons au passage les termes les plus fréquents :
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| word | food | order | place | time | like | servic | go | get | good | one | us | back | would | ask | wait | even | restaur | tabl | minut | came |
| count | 18396 | 16764 | 12171 | 10518 | 10044 | 9890 | 9291 | 9202 | 8882 | 8746 | 8164 | 7942 | 7863 | 7087 | 6769 | 6667 | 6580 | 5713 | 5624 | 5592 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| word | got | come | never | want | tri | said | realli | tast | eat | look | drink | chicken | manag | server | went | could | say | 2 | make | custom |
| count | 5562 | 5527 | 5254 | 5103 | 5045 | 4887 | 4815 | 4665 | 4560 | 4454 | 4447 | 4408 | 4056 | 4014 | 4001 | 3975 | 3922 | 3888 | 3793 | 3769 |
699154 [2, 0, 1, 1, 1, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, ...
1194101 [0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, ...
1025304 [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ...
58303 [1, 3, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 5, ...
182858 [0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, ...
...
3947719 [2, 3, 0, 1, 0, 2, 2, 1, 0, 4, 3, 0, 6, 1, 2, ...
2401000 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ...
1715625 [2, 2, 0, 0, 0, 2, 4, 2, 0, 1, 0, 3, 0, 0, 0, ...
1402530 [0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, ...
1657147 [1, 0, 0, 1, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, ...
Name: vector, Length: 20000, dtype: object
| food | order | place | time | like | servic | go | get | good | one | ... | jump | traffic | balanc | boneless | slowest | tag | tall | competit | picki | success | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 699154 | 2 | 0 | 1 | 1 | 1 | 0 | 3 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1194101 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1025304 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 58303 | 1 | 3 | 2 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 182858 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3947719 | 2 | 3 | 0 | 1 | 0 | 2 | 2 | 1 | 0 | 4 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2401000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1715625 | 2 | 2 | 0 | 0 | 0 | 2 | 4 | 2 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1402530 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1657147 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 2 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
20000 rows × 2000 columns
Classification non supervisée des topics : On va maintenant effectuer le clustering de notre bag of words...On commence par reprendre la méthode du coude utilisée au projet précédent :
<AxesSubplot:title={'center':'KMeans : somme des inerties intra-cluster vs nb topics\n bag-of-words et vectorisation basiques'}>
Ca fait beaucoup d'inertie même à 20 clusters, et on n'a pas vraiment de coude franc. Voyons si on peut faire mieux en résumant nos 1000 variables avec une ACP.
Les 525 composantes principales décrivent81.93020749130164 % de la variation totale du dataset
<AxesSubplot:title={'center':'KMeans : somme des inerties intra-cluster vs nb topics\n bag-of-words et vectorisation basiques + ACP '}>
On va la tenter en 8 clusters et voir quels top-words on obtient pour chaque topic :
KMeans()
Cluster 0: ['food', 'order', 'servic', 'place', 'go', 'time', 'good', 'like', 'get', 'back', 'one', 'even'] Cluster 1: ['us', 'time', 'servic', 'get', 'food', 'one', 'go', 'ask', 'back', 'order', 'wait', 'tabl'] Cluster 2: ['order', 'food', 'time', 'get', 'wait', 'place', 'go', 'back', 'ask', 'minut', 'would', 'servic'] Cluster 3: ['pizza', 'order', 'place', 'time', 'would', 'like', 'one', 'go', 'call', 'get', 'good', 'chees'] Cluster 4: ['food', 'like', 'place', 'order', 'good', 'one', 'time', 'tast', 'go', 'restaur', 'get', 'would'] Cluster 5: ['food', 'place', 'good', 'like', 'order', 'servic', 'go', 'time', 'get', 'tast', 'chicken', 'would'] Cluster 6: ['us', 'food', 'order', 'ask', 'tabl', 'wait', 'minut', 'time', 'one', 'back', 'get', 'servic'] Cluster 7: ['order', 'food', 'us', 'tabl', 'time', 'ask', 'get', 'would', 'one', 'wait', 'restaur', 'go']
Puis on visualise nos clusters sur un plan obtenu par tsne :
On observe déjà une séparation mais tous les clusters ne sont pas clairement séparés dans notre espace en 2d.
Le vocabulaire limité y est peut être pour quelque chose.
Sans normalisation, les termes les plus fréquents restent plus ou moins
les mêmes et ne sont pas très informatifs ni très différenciants.
Voyons si on peut faire mieux avec d'autres outils.
On
va maintenant utiliser les vectorizers de la famille scikitlearn, qui
permettent d'effectuer toutes les opérations de pré-traitement en une
fois.
<20000x10000 sparse matrix of type '<class 'numpy.int64'>' with 909216 stored elements in Compressed Sparse Row format>
Après différents essais et autant de résultats incohérents, il s'avère que la fonction de mesure a un bug (voir cas #6777 et #7992 sur le Github de ScikitLearn) et n'est fiable que lorsqu'elle travaille sur des monogrammes tf. On va donc choisir le meilleur nombre de topics en se basant sur un modèle simplifié, puis on utilisera le nombre de topics déterminé sur nos modèles plus élaborés.
<20000x9149 sparse matrix of type '<class 'numpy.int64'>' with 769406 stored elements in Compressed Sparse Row format>
<AxesSubplot:title={'center':'LDA log-likelihood score vs n_topics\n monograms'}>
LatentDirichletAllocation(learning_method='online', learning_offset=50.0,
n_components=5)
Topic 0: place like just burger time fries good really location want better going coffee know people Topic 1: steak sushi fish better good price quality restaurant roll service worth rolls just buffet average Topic 2: order said minutes time asked told service manager customer ordered just didn came waited pizza Topic 3: chicken ordered like good sauce just place salad tasted taste really meat cheese didn came Topic 4: service table restaurant time server came good place drinks night experience just room waitress people
Le tout implémenté sous forme de pipeline :
Pipeline(steps=[('vectorize',
StemmedCountVectorizer(max_df=0.5, max_features=10000,
min_df=5, ngram_range=(1, 3),
stop_words='english',
strip_accents='unicode',
token_pattern='\\b[a-zA-Z]{4,}\\b')),
('LDA',
LatentDirichletAllocation(learning_method='online',
learning_offset=50.0,
n_components=5))])
C:\Users\Wince\Downloads\OC\Projet_6\data
| business_id | caption | label | |
|---|---|---|---|
| photo_id | |||
| 001kKc6P_rmgaXThAHxEkw | zKZc8GwCaKbACaV0HZAmpg | Clean and simple interior | inside |
| 002gqWfVal1D2DT6oA-bVQ | qnZzSC4TKen19Gz9nyKCvw | 12oz. Boneless Ribeye | Grilled to perfection ... | food |
| 002GtTSYyQ4swIZyEnfF5A | 9km51KaQujxsSgdaG9gYSw | The Most Yummy Tarts: Chantilly, Guava, Salted... | food |
| 0036yehPJxVwNZDRDYH2jQ | Qg9L37JCd-PkcWMj9VAWmw | Dynamic Duo! Great dance music! | inside |
| 003Isvt6NCJ567PdAEwrfA | zgQHtqX0gqMw1nlBZl2VnQ | food | |
| ... | ... | ... | ... |
| ZZZe7u0FOUIViEHdZyiLdQ | EkWxaYNt92DPjwXik7TbAQ | Honey Garlic Pizza | food |
| zZzjnzvMPoToXJpej1AI8w | xfCgxY_SQfzxFsQjNiLJEQ | I'm from LA and could not walk by wo stopping.... | inside |
| ZZzMJaFD6f6DTUHEb23zxA | NtiBsNppXU0XS4zM89dphQ | STC TASTE MRKT - A new food experience | inside |
| ZzZW8rydLi9ZrpwTFJ5amw | cYwJA2A6I12KNkm2rtXd5g | inside | |
| ZZZZw6bhGibK29E5Na9Pag | PIvOFRxQZLlhXZRO9o5ujg | Monday nights | inside |
200000 rows × 3 columns
| business_id | caption | label | |
|---|---|---|---|
| count | 200000 | 200000 | 200000 |
| unique | 39830 | 72475 | 5 |
| top | RESDUcs7fIiihp38-d6_6g | food | |
| freq | 652 | 107420 | 118597 |
Voyons les légendes les plus courantes pour nos photos :
107420 Inside 531 Interior 502 Menu 311 McDonald's Quarter Pounder with Cheese Extra Value Meal 297 McDonald's Snacks & Sides Menu Items 286 McDonald's Buttermilk Crispy Chicken Sandwich Extra Value Meal 284 McDonald's Dessert Menu Items 281 McDonald's Artisan Grilled Chicken Sandwich Extra Value Meal 280 McDonald's Double Cheeseburger Extra Value Meal 274 McDonald's All Day Breakfast Menu Items 257 Bar 255 McDonald's Big Breakfast: biscuit, scrambled eggs, hot sausage, and hash browns. 212 Outside 162 Bar area 140 Entrance 135 Exterior 112 Bacon King Jr 107 Dining area 107 Onion Rings 100 Storefront 94 Dining room 92 Decor 88 Dining Room 87 McDonald's Big Breakfast: biscuit, scrambled eggs, hot sausage, and hash browns 85 Nuggets 85 McDonald's All Day Breakfast Sandwiches 84 Chicken Fries 84 BK Coffee 84 Whopper 82 www.balletossington.com 79 Front 74 The bar 65 Patio 61 Chipotle Chicken, Scrambled Egg & Avocado Wrap 60 Seating area 59 Baja Grain Bowl with Chicken 57 Nachos 57 Chicken Egg Rolls 56 Modern Greek Salad 54 Kitchen 53 Strawberries Vanilla Crepe Breakfast 51 Broccoli Beef 50 Kung Pao Chicken and Grilled Teriyaki Chicken Plate 49 Oysters 48 Zesty Nachos 46 Double Cheeseburger 45 Roasted Turkey, Apple & Cheddar 45 NEW! Strawberry Pancake Puppies 45 Takoyaki 45 Name: caption, dtype: int64
Et voyons la distribution des étiquettes :
food 118597 inside 53795 outside 13652 drink 12278 menu 1678 Name: label, dtype: int64
On a donc des étiquettes catégoriques concernant les photos qu'on va pouvoir utiliser pour entraîner un classifieur. En tout cas on va commencer par essayer une approche supervisée.
On nettoie l'index en retirant les noms commencant par un - , qui seraient générateurs d'erreurs :
On va ensuite générer des images de la classe "menu", qui sont très
largement minoritaires. On va en générer 7 par fichier, soit un peu plus
qu'il n'en faudrait pour équilibrer le dataset sur la base de la classe
"drink".
Le code est visible ci dessous, mais ne sera pas exécuté.
Par souci de fluidité on préfère utiliser un set d'images générées lors
d'une exécution préalable :
from keras.preprocessing.image import ImageDataGenerator, array_to_img
from keras.preprocessing.image import img_to_array, load_img
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
for n in img_meta[img_meta.label == 'menu'].index:
img = load_img(wd+r'\'+n + '.jpg')
x = img_to_array(img)
x = x.reshape((1,) + x.shape)
i = 0
for batch in datagen.flow(x, batch_size=1, save_to_dir='generated',
save_prefix=n, save_format='jpg'):
i += 1
if i > 6:
break
Ici on utilise les noms des fichiers générés pour remplir le df de métadonnées dont l'index servira de base pour l'adressage lors des différents traitements des fichiers :
| business_id | caption | label | |
|---|---|---|---|
| photo_id | |||
| _XPk-tlTv7KrWu43sBMq6Q_0_2814 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _XPk-tlTv7KrWu43sBMq6Q_0_5380 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _XPk-tlTv7KrWu43sBMq6Q_0_6297 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _XPk-tlTv7KrWu43sBMq6Q_0_7587 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _XPk-tlTv7KrWu43sBMq6Q_0_902 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _XPk-tlTv7KrWu43sBMq6Q_0_9179 | _GLjUkVPjRmu6ASmQZbmyg | Menu and specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_1753 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_5788 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_7383 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_7454 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_8760 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_8993 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _xRxXK9jzGUGWFXFbDR8ig_0_9564 | n2NRR4N-kmeDvhHJivHGkA | Happy hour specials | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_505 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_5790 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_7040 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_7100 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_8073 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_9005 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_9109 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
food 116821 inside 52964 outside 13433 menu 13205 drink 12090 Name: label, dtype: int64
On filtre nos données pour prendre uniquement des photos des businesses de la catégorie restaurant :
| business_id | caption | label | |
|---|---|---|---|
| photo_id | |||
| 001kKc6P_rmgaXThAHxEkw | zKZc8GwCaKbACaV0HZAmpg | Clean and simple interior | inside |
| 002GtTSYyQ4swIZyEnfF5A | 9km51KaQujxsSgdaG9gYSw | The Most Yummy Tarts: Chantilly, Guava, Salted... | food |
| 004hKk-Nx9UNpIUh5XZ3fA | EUWBT5GDxPC95w9itZ1EHw | outside | |
| 006ZHlSqUxlUDaBN94O7Cw | a0v7Si0DK4cIko7AQY4YXg | food | |
| 007FeerwcQQRx7ck_xA0QA | nsNONDHbV7Vudqh21uicqw | Surf and turf with 1.5lb lobster and 7oz Filet... | food |
| ... | ... | ... | ... |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_7040 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_7100 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_8073 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_9005 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
| _YP1JaaKVFfZ5HWmn4RU_Q_0_9109 | zWFuGjtmzekVBTL0muNsXw | Chicken Sandwiches | menu |
91082 rows × 3 columns
Grâce à ces images, on va pouvoir créer un set d'images équilibré pour permettre un apprentissage équilibré des classes.
| business_id | caption | label | |
|---|---|---|---|
| photo_id | |||
| 02gsqO6SQfesH8qcoZ7J8g | qE9yIXn2GQb2-4a_qOOKzg | drink | |
| 02jlAqlH35nW9NKkDbAptg | IhNASEZ3XnBHmuuVnWdIwA | Hokkaido Boba Tea : best one yet! | drink |
| 02LI6iJ-NEEt9c8aHzZZDg | DMyoxEaTGTakZxWgh1D5bw | Our Wine Bar is pouring some of the most celeb... | drink |
| 05EjQX2FOlHT-vQrwC4t_A | u73j2VQ3TGWdMO-AG7MABw | drink | |
| 06N0-UjADarro_AE_E3UFQ | fobFqG-4X6XhDsuW7rb85w | Mimosa Flight | drink |
| ... | ... | ... | ... |
| ReSWj5Qn1nttjUmVAiTB7A | Fv3HvJPQYqfmniTgtIQJzA | outside | |
| l1Z3DnA5ajaH7soSqSxAoQ | 41lQvgIQEfEmqINKciNGxg | outside | |
| rlbkyCp2tN36UKWNET8fzQ | dAmVTQ6ukuLh4UxTmBoRkg | Very busy lines.... we going to wait to c what... | outside |
| SVxJOgb1rYSCmdAadLSo8g | huOCKRwDvNqGX3KSzYawbw | outside | |
| S_fxEAPiLUvQEceZUB6P8g | oNGV2UdhUokFc11xktt7ow | Garden Wedding Ceremony Setup at the Bow Valle... | outside |
23360 rows × 3 columns
On a maintenant un tableau de métadonnées qui contient un jeu de
photos équilibré du point de vue des labels.
On va pouvoir charger les photos qui nous intéressent en ram afin de les
traiter et de voir si on peut les étiqueter automatiquement.
Avant, on resample nos données pour avoir un nombre fixe d'images, cela facilitera le suivi de nos opérations de traitement.
['bl4W5cuxWTMqb73AupxOWQ.jpg', 'Dgk-m45hFFKnKPS0KjcupQ.jpg', '21kUG-l53_YLjHGLEUVhIA.jpg', 'nCkXc7v3PYy4_iQbzBocnw.jpg', '7xnrypOnY9tCqv91Z0rNCw.jpg']
On crée notre galerie d'images :
On commence par encoder nos catégories et créer un jeu d'entrainement et un jeu de validation avec notre galerie d'images.
Puis on définit des fonctions de pré-traitement qu'on va mettre sous forme de pipeline en utilisant la classe Function_transformer. D'abord pour un traitement en couleurs avec ORB.
Voici les transformations successives que va subir chacune des images traités par cette fonction (à ceci près qu'on démontre le traitement en RGB pour visionner avec matplotlib, au lieu de traiter des images en BGR comme chez openCV) :
On fait la même chose pour l'extraction de features via ORB, mais cette fois on va intégrer les fonctions de détections de features sous forme de méthodes fit et predict appartenant à une sous-classe de transformermixin (la classe de base des transformateurs scikit-learn).
On définit également une fonction de pré-traitement et un détecteur de features avec SIFT.
Avant de tester nos modèles, on met en place un classifieur aléatoire qui sera notre baseline pour évaluer la capacité d'apprentissage de notre modèle
baseline ROC_AUC:0.4948329513683408
Pipeline(steps=[('preprocess',
FunctionTransformer(func=<function grayscale_preprocessing at 0x00000245C93191F0>)),
('detect_features', Sift_Featurizer()),
('classify', RandomForestClassifier(class_weight='balanced'))])
Visualisation sur un exemple du pré-traitement avant détection de features par SIFT :
Faisons maintenant une prédiction sur le jeu de test avec notre pipeline juste entraîné :
| predicted | actual | |
|---|---|---|
| _rOE3rPrKmAj2U_HsU_Otw.jpg | food | food |
| 46YDGMImrBmzUrJ9UULvbQ_0_4908.jpg | menu | menu |
| aMcKbyW8lvtrpLQnxJPRgA.jpg | food | outside |
| tNxnnBAcQ2LjTHCDfrNKLA.jpg | food | food |
| c3rbiHJVhEBfKWdfLk3alg.jpg | outside | inside |
| Q-tNNk8d8Xtm2m6t18iYqw.jpg | drink | inside |
| c1U136_krmc5IfHhhqDV7A.jpg | inside | outside |
| 71IzF-jk5f4IzrHMcT1GIw.jpg | inside | outside |
| iuszcJhcoUVPjGNnWrkFwA.jpg | inside | food |
| xzA262KNYfSmstIPvy9U5w.jpg | inside | inside |
Voyons la matrice de confusion des prédictions faites pour notre jeu de test :
| True Negative | False Positive | False Negative | True Positive | |
|---|---|---|---|---|
| drink | 868 | 95 | 90 | 147 |
| food | 848 | 88 | 105 | 159 |
| inside | 833 | 111 | 126 | 130 |
| menu | 933 | 30 | 52 | 185 |
| outside | 850 | 144 | 95 | 111 |
Présenté de façon plus lisible (étiquettes prédites vs étiquettes réelles) :
| drink | food | inside | menu | outside | |
|---|---|---|---|---|---|
| actual | |||||
| drink | 147 | 47 | 24 | 7 | 17 |
| food | 44 | 159 | 22 | 14 | 8 |
| inside | 18 | 23 | 130 | 11 | 59 |
| menu | 3 | 6 | 10 | 185 | 11 |
| outside | 25 | 29 | 70 | 20 | 111 |
Ou décrit avec un simple score à comparer avec notre baseline :
ROC_AUC du combo sift-kmeans200-random_forest : 0.8765924224549542
Pipeline(steps=[('preprocess',
FunctionTransformer(func=<function preprocessing at 0x00000245D24EDF70>)),
('detect_features', Orb_Featurizer()),
('classify', RandomForestClassifier(class_weight='balanced'))])
On crée et fitte notre pipeline avec ORB de la même façon qu'avec
SIFT puis on regarde les résultats obtenus en prédisant les classes de
notre jeu de test :
| drink | food | inside | menu | outside | |
|---|---|---|---|---|---|
| actual | |||||
| drink | 136 | 35 | 27 | 28 | 16 |
| food | 60 | 90 | 40 | 30 | 27 |
| inside | 39 | 39 | 85 | 31 | 47 |
| menu | 11 | 30 | 24 | 120 | 30 |
| outside | 40 | 60 | 37 | 61 | 57 |
ROC_AUC du combo orb_couleur-kmeans200-random_forest : 0.7131945081976935
Différents essais ont été menés, avec 200 ou 500 features extraits, des images couleur et en nuances de gris, en détectant les features par SIFT et ORB. Ni la couleur ni le nombre de features ne semble apporter d'avantage dans l'efficacité du modèle. On garde donc pour le notebook livrable les modèles ORB et sift à 200 features, afin d'offrir un comparatif tout en gardant des temps d'exécution raisonnables.
Différents classifieurs ont également été testés, on ne propose ici que le plus simple et efficace : RandomForest.
On
définit d'abord notre modèle d'extraction (on garde les poids Imagenet
et on récupère l'output sur l'avant dernière couche vgg16)
Puis on définit la fonction et le transformateur de preprocessing.
On l'exécute et on vérifie la forme de l'output :
(1, 4096)
On définit une fonction d'extraction des features, qu'on exécute sur notre galerie d'images prétraitées.
On vérifie la forme :
(4800, 4096)
On va maintenant réduire le nombre de variables, voyons si une
PCA à 200 composantes donnerait un bon "résumé" de notre dataset :
Les 250 composantes principales décrivent 77.90662426080532 % de la variation totale du dataset
Pas tout à fait...Pour simplifier, on va fitter notre pca automatiquement pour qu'elle soit représentative de 90% de la variance totale de notre bag of features
PCA(n_components=0.9, svd_solver='full')
On couvre une proportion appréciable de la variance de notre jeu
de features, on va donc garder notre PCA telle quelle.
On va maintenant transformer nos données puis les regrouper en clusters à
l'aide de KMeans. Voyons déjà quel serait le nombre de clusters le plus
approprié :
(4800, 773)
<AxesSubplot:title={'center':'KMeans : somme des inerties intra-cluster vs nb catégories\nYelp Photos, VGG16 + PCA'}>
On va donc garder 5 clusters dans notre segmentation. On définit maintenant le pipeline regroupant tous les traitements et aboutissant à la segmentation :
Pipeline(steps=[('preprocess',
FunctionTransformer(func=<function vgg_preprocess at 0x00000246D7A0C820>)),
('detect_features',
FunctionTransformer(func=<function featurize_values at 0x0000024731959CA0>)),
('reduce_features', PCA(n_components=0.9, svd_solver='full')),
('cluster', KMeans(n_clusters=5))])
On
va maintenant réduire nos features à 2 dimensions afin de créer un
espace propice à la visualisation de nos clusters d'image :
On se crée une galerie de miniatures en RGB pour la visualisation, et on va sélectionner aléatoirement quelques images parmi notre jeu d'entraînement :
| d1 | d2 | cluster | |
|---|---|---|---|
| 2475 | 2.654671 | 25.698782 | 2 |
| 3919 | 2.680990 | -64.617050 | 1 |
| 1001 | -41.448086 | -13.842228 | 0 |
| 2604 | -35.026340 | -26.441826 | 0 |
| 1248 | -27.425997 | 59.887260 | 2 |
Voyons l'ARI de notre clustering par rapport aux étiquettes fournies :
0.7142181044716431
array([1, 0, 2, ..., 3, 4, 3])
C'est un bon début, l'ARI est plus proche de 1 que de 0...Voyons
plus directement quelques photos de notre échantillon aléatoire classées
par cluster prédit :
C'a l'air plutôt bien...Mais refitter une couche de notre CNN pourrait sans doute améliorer sa performance.
On va entraîner les dernières couches du réseau avec nos images et nos étiquettes catégoriques, avant de faire un clustering. D'abord, on reconstitue notre train d'étiquettes textuelles :
| filename | label | |
|---|---|---|
| 0 | NVFw6SBR3PHzZAb3gaNA4Q_0_7135.jpg | NaN |
| 1 | 9do9ZkZ1MqNEORYO94hXiQ.jpg | NaN |
| 2 | v8AucVeblJ-fKnsK2L6FWQ.jpg | NaN |
| 3 | yUBcV9iy194fqm7iWbE37g.jpg | NaN |
| 4 | cNX1_3Q1S_NQSicWQhp62A_0_13.jpg | NaN |
| ... | ... | ... |
| 4795 | azjVJOb_441YolTM352J4w.jpg | NaN |
| 4796 | I7CQS3ckVH7xQiZ7VrVDhg.jpg | NaN |
| 4797 | Yci7Li7LwOslgPMZcgzQuQ.jpg | NaN |
| 4798 | 7TKWFoDurCP9c1QZhsU62g.jpg | NaN |
| 4799 | wKAPhS5UMMIZ-HTVBeJOrQ_0_4023.jpg | NaN |
4800 rows × 2 columns
On adapte notre fonction de preprocessing, puis on l'exécute pour vérifier qu'on a bien les dimensions attendues :
(4800, 224, 224, 3)
On encode nos étiquettes textuelles en variable catégorique pour
Keras et on construit notre modèle, dont on vérifie la constitution :
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) [(None, 224, 224, 3)] 0 _________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ block1_conv2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ block1_pool (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ block2_conv1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ block2_conv2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ block2_pool (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ block3_conv1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ block3_conv2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_conv3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_pool (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_pool (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_pool (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc1 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc2 (Dense) (None, 4096) 16781312 _________________________________________________________________ dense (Dense) (None, 5) 20485 ================================================================= Total params: 134,281,029 Trainable params: 16,801,797 Non-trainable params: 117,479,232 _________________________________________________________________
On fitte notre modèle puis on définit et on fitte notre pipeline :
WARNING:tensorflow:AutoGraph could not transform <bound method Dense.call of <keras.layers.core.Dense object at 0x000002439424D910>> and will run it as-is. Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: invalid syntax (tmpyriu9efa.py, line 48) To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <bound method Dense.call of <keras.layers.core.Dense object at 0x000002439424D910>> and will run it as-is. Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: invalid syntax (tmpyriu9efa.py, line 48) To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
<keras.callbacks.History at 0x24661577880>
Pipeline(steps=[('preprocess',
FunctionTransformer(func=<function vgg_preprocess at 0x00000246C4FF6B80>)),
('detect_features',
FunctionTransformer(func=<function featurize_values at 0x00000246B5902310>)),
('reduce_features', PCA(n_components=0.9, svd_solver='full')),
('cluster', KMeans(n_clusters=5))])
On réduit encore notre espace par tSNE pour visualiser nos
clusters sur 2 dimensions, toujours avec 200 images prises au hasard :
| d1 | d2 | cluster | |
|---|---|---|---|
| 11 | 14.406443 | -43.576618 | 2 |
| 2584 | 38.787739 | 19.094782 | 4 |
| 61 | -46.244846 | -11.401321 | 4 |
| 3534 | 53.884777 | -6.809408 | 4 |
| 344 | -48.967442 | 8.610932 | 3 |
| ... | ... | ... | ... |
| 37 | 1.476462 | -61.452801 | 2 |
| 3621 | 19.416666 | -28.055346 | 2 |
| 3980 | -59.904778 | 6.614191 | 3 |
| 1132 | -20.431669 | -14.350131 | 3 |
| 272 | 20.382607 | -27.996849 | 2 |
200 rows × 3 columns
Voyons plus simplement un échantillon pris dans chaque cluster :
Faisons nos prédictions et voyons l'ARI de notre clustering par rapport aux étiquettes fournies :
| predicted_cluster | actual | |
|---|---|---|
| _rOE3rPrKmAj2U_HsU_Otw.jpg | 4 | food |
| 46YDGMImrBmzUrJ9UULvbQ_0_4908.jpg | 2 | menu |
| aMcKbyW8lvtrpLQnxJPRgA.jpg | 0 | outside |
| tNxnnBAcQ2LjTHCDfrNKLA.jpg | 4 | food |
| c3rbiHJVhEBfKWdfLk3alg.jpg | 3 | inside |
| Q-tNNk8d8Xtm2m6t18iYqw.jpg | 3 | inside |
| c1U136_krmc5IfHhhqDV7A.jpg | 0 | outside |
| 71IzF-jk5f4IzrHMcT1GIw.jpg | 3 | outside |
| iuszcJhcoUVPjGNnWrkFwA.jpg | 4 | food |
| xzA262KNYfSmstIPvy9U5w.jpg | 3 | inside |
0.7233321230270465
On a déjà amélioré notre modèle en peu de temps...SI on peut lui fournir tous nos exemples et réentraîner plus de couches, on peut probablement arriver à de très bons résultats.
On
importe les librairies nécessaires, on adresse les clés d'API et le
type d'objet transmis pour formuler la requête (ici json) en en-tête du
message. On crée le transport (la librairie GraphQL formule les requêtes
http à partir d'une URL, une en-tête, et d'autres paramètres
optionnels) puis le client (la classe qui formule les requêtes à travers
un transport préalablement défini), on formule notre requête selon la
syntaxe expliquée dans le guide d'API Yelp, on exécute et on récupère la
réponse.
On fait d'abord une recherche des restaurants sur la ville de Vancouver
(wa) en incluant les champs qui peuvent apporter des infos pertinentes
pour notre application.
Voici à quoi ressemblent les données renvoyées :
C:\Users\Wince\Downloads\OC\Projet_6\Data
2152
| name | id | rating | photos | |
|---|---|---|---|---|
| 0 | Thai Wok Kitchen | IMYh4LJm1ubY5Lw3rz-aqA | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/DTGvv... |
| 1 | I Heart Gyro | szJPyyYqJRxithtH6r6O9g | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/QtNH2... |
| 2 | Brewed Cafe & Pub | Prp0oy6V21P24bdvQ0Vhzw | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/853h9... |
| 3 | Abhiruchi Indian Cuisine South and North | jcykhIgB0cXLjSBkuet4WA | 4.5 | [https://s3-media2.fl.yelpcdn.com/bphoto/B7118... |
| 4 | Thai Champa | xeFke1EuoYXOZaX1rTQYEw | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/b7QQD... |
| 5 | Amaro's Table | g_BPftmJpuu2yEYaBS6yLQ | 4.5 | [https://s3-media2.fl.yelpcdn.com/bphoto/jxOOb... |
| 6 | Pine State Biscuits | 5oed6H5F8qZxNzELq_1e1w | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/XUBi0... |
| 7 | Thai Orchid Restaurant | JkhXi-3RJtmUTlkjrSdWSw | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/Lm0mH... |
| 8 | River Maiden | x_V8wDr6Ws03Y5Yqg2n7jg | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/iTEzC... |
| 9 | Pip's Original Doughnuts & Chai | MVm6pgnnd6Sg_LdtUhkGuw | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/IOLkS... |
On définit maintenant une fonction en jouant sur le paramètre offset pour obtenir le nombre de restaurants désiré.
Vérifions la taille du df obtenu :
(200, 4)
Maintenant qu'on a le nombre d'identifiants désirés pour notre
test, il reste à formuler une requête à l'endpoint Reviews pour
récupérer le texte et la note des reviews concernant ce business.
On agglomère le tout en un seul df :
| rating | text | id | name | avg_stars | photos | |
|---|---|---|---|---|---|---|
| 0 | 5 | This was a great surprise. Great food and cho... | IMYh4LJm1ubY5Lw3rz-aqA | Thai Wok Kitchen | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/DTGvv... |
| 1 | 5 | My favorite spot for Thai food take out. This... | IMYh4LJm1ubY5Lw3rz-aqA | Thai Wok Kitchen | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/DTGvv... |
| 2 | 5 | So honestly I can't believe I have not posted ... | IMYh4LJm1ubY5Lw3rz-aqA | Thai Wok Kitchen | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/DTGvv... |
| 3 | 5 | This place is awesome even during COVID \nThis... | szJPyyYqJRxithtH6r6O9g | I Heart Gyro | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/QtNH2... |
| 4 | 5 | I heart gyro is my go-to place when I'm lookin... | szJPyyYqJRxithtH6r6O9g | I Heart Gyro | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/QtNH2... |
| ... | ... | ... | ... | ... | ... | ... |
| 595 | 5 | I started going to trap door when I first move... | _bRifScQCMjlX8K8r6L5Ww | Trap Door Brewing | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/z1RGp... |
| 596 | 4 | As taprooms go, this one is my favorite. \nIPA... | _bRifScQCMjlX8K8r6L5Ww | Trap Door Brewing | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/z1RGp... |
| 597 | 5 | The pupusas here...... I love them. After givi... | VWbDjYlf0X49P6TYFROeHw | mi casa pupuseria y Mexican restaurant | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/S6gvN... |
| 598 | 5 | We are in the Time of Takeout, people. Mi Casa... | VWbDjYlf0X49P6TYFROeHw | mi casa pupuseria y Mexican restaurant | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/S6gvN... |
| 599 | 5 | I was very excited to read the reviews of this... | VWbDjYlf0X49P6TYFROeHw | mi casa pupuseria y Mexican restaurant | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/S6gvN... |
600 rows × 6 columns
Reste à filtrer par rating - l'api n'a pas de paramètre pour filtrer ce dernier :
| rating | text | id | name | avg_stars | photos | |
|---|---|---|---|---|---|---|
| 50 | 1 | Had dinner last night with wife and friends...... | rgGJMwcrNTuCcY493q_YuA | Frontier Public House | 4.0 | [https://s3-media3.fl.yelpcdn.com/bphoto/jMaaI... |
| 86 | 1 | Ordered a beef and lamb rice platter because t... | i3kLmyzSmOgYXLOXiNMHLw | Anoush-Deli & International Food Market | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/Xgodb... |
| 128 | 2 | Customer service was great! So I have no compl... | BDX4VYxx_DpuAEnNYKYYZQ | Main Event Sports Grill | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/ICGU2... |
| 152 | 1 | Whoa , whoa , whoa don't go to this location, ... | 1tQLwff_HPcbSSDmHTl1Cg | Killer Burger | 4.0 | [https://s3-media3.fl.yelpcdn.com/bphoto/pTHMG... |
| 173 | 1 | I came into the shop to buy beer.\nSomeone fro... | yvWgHaRjKS5bPy4Hr_l-2Q | Ben's Bottle Shop | 4.5 | [https://s3-media2.fl.yelpcdn.com/bphoto/hmY1v... |
| 188 | 2 | 3/15/21 The Tale of Two Stories:\n\nWe arrived... | vTpWN7GpDJHQaoiZ3G-3Gw | The Rock Wood Fired Pizza | 3.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/dWiV2... |
| 368 | 2 | Sorry for the harsh review. I've come to reali... | dZ9UC9pP7rep5oNdUABtwQ | DesiPDX | 4.5 | [https://s3-media1.fl.yelpcdn.com/bphoto/ODi_I... |
| 383 | 2 | It was okay! Ordered a basic breakfast. Sausa... | iQr4p4LxH3zi3Qx5a74ZoA | Christine's Restaurant | 4.0 | [https://s3-media2.fl.yelpcdn.com/bphoto/PKxwk... |
| 454 | 1 | Shitty part of town and even shittier customer... | TaeWwshEBr-SQcfDgvMthQ | Don Taco | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/fZ9JT... |
| 455 | 2 | Two stars - I actually ordered from here confu... | TaeWwshEBr-SQcfDgvMthQ | Don Taco | 4.0 | [https://s3-media4.fl.yelpcdn.com/bphoto/fZ9JT... |
| 463 | 1 | FLIES EVERYWHERE. My first warning sign should... | Ef5uqwdfz1gZqKIEbAxKhQ | Boomerang | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/cAs-3... |
| 515 | 2 | I have been frequenting this place since openi... | sSf3aPUHXRMlWDNwPyjqZg | Pho Sen | 4.0 | [https://s3-media1.fl.yelpcdn.com/bphoto/o6W6R... |
| 557 | 2 | I can see this is a family restaurant and I wa... | 5AQR4mka_xM6JhW2zfRGrg | Nayhely's Place | 4.0 | [https://s3-media2.fl.yelpcdn.com/bphoto/JMDKI... |
| 592 | 1 | Poor and rude Service from bartender, Anthony,... | WBhSjHyoo4Hqi0YLNlOsgA | Niche Wine Bar | 4.5 | [https://s3-media3.fl.yelpcdn.com/bphoto/Hmqc9... |
On a bien peu de mauvaises reviews pour nos 600 lignes, mais on peut
imaginer envoyer les requêtes et filtrer le rating dans une boucle while
pour avoir autant de reviews négatives qu'on veut, dans la limite de
l'existant bien sûr.
Nos données sont maintenant sauvegardées, et identifiables, reste à
savoir si la limite de 3 reviews et une url de photo sera suffisante
pour notre use case...